﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace PayloadTracker.APRS
{
    public class Tools
    {
        // Used to convert knots into miles per hour
        public static double MPHPerKnot = double.Parse("1.150779", CultureInfo.CurrentCulture);
        public static double FeetPerMeter = double.Parse("3.2808399", CultureInfo.CurrentCulture);
        /// <summary>
        /// Convert GPS string to decimal degrees.
        /// </summary>
        /// <param name="GPS"></param>
        /// <param name="Bearing"></param>
        /// <returns></returns>
        /// 
        
        public static double GPSToDecimalDegrees(string GPS, string Bearing)
        {
            try
            {
                if (GPS == string.Empty)
                    return double.MinValue;

                //Get the fractional minutes
                string tmp = GPS.Substring(GPS.IndexOf("."));
                double FractionalMinutes = double.Parse(GPS.Substring(GPS.IndexOf(".")));

                //Get the minutes.
                tmp = GPS.Substring(GPS.IndexOf(".") - 2, 2);
                double Minutes = double.Parse(GPS.Substring(GPS.IndexOf(".") - 2, 2));

                //Get the degrees
                tmp = GPS.Substring(0, GPS.IndexOf(".") - 2);
                double Degrees = double.Parse(GPS.Substring(0, GPS.IndexOf(".") - 2));


                double DecimalDegrees = Degrees + (Minutes + FractionalMinutes) / 60;
                return (Bearing == "S" || Bearing == "W") ? -DecimalDegrees : DecimalDegrees;
            }
            catch
            {
                return double.MinValue;
            }
        }
        /// <summary>
        /// Convert NMEAUTC time to a DateTime type.
        /// </summary>
        /// <param name="NMEAUTCTime"></param>
        /// <returns></returns>
        public static DateTime NMEAUTCTimeToUTCDateTime(string NMEAUTCTime)
        {
            TimeSpan ts = new TimeSpan(int.Parse(NMEAUTCTime.Substring(0, 2)),
                                       int.Parse(NMEAUTCTime.Substring(2, 2)),
                                       int.Parse(NMEAUTCTime.Substring(4, 2)));

            TimeZone localZone = TimeZone.CurrentTimeZone;
            DateTime UTCTime = DateTime.UtcNow.Add(-DateTime.UtcNow.TimeOfDay).Add(ts);
            TimeSpan currentOffset = localZone.GetUtcOffset(DateTime.Now);
            DateTime UTCTimeAdjusted = UTCTime.Add(currentOffset);
            return UTCTimeAdjusted;
        }

        public static DateTime NMEAUTCTimeToLocalTime(string NMEAUTCTime)
        {
            int UtcHours = Convert.ToInt32(NMEAUTCTime.Substring(0, 2));
            int UtcMinutes = Convert.ToInt32(NMEAUTCTime.Substring(2, 2));
            int UtcSeconds = Convert.ToInt32(NMEAUTCTime.Substring(4, 2));
            int UtcMilliseconds = 0;
            // Extract milliseconds if it is available
            if (NMEAUTCTime.Length > 7)
            {
                UtcMilliseconds = Convert.ToInt32(float.Parse(NMEAUTCTime.Substring(6), CultureInfo.CurrentCulture) * 1000);
            }
            // Now build a DateTime object with all values
            System.DateTime Today = System.DateTime.Now.ToUniversalTime();
            DateTime Time;
            try
            {
                System.DateTime SatelliteTime = new System.DateTime(Today.Year, Today.Month, Today.Day, UtcHours, UtcMinutes, UtcSeconds);
                // Set the new time, adjusted to the local time zone
                Time = SatelliteTime.ToLocalTime();
            }
            catch
            {
                //HACK!
                Time = DateTime.Now;
            }
            
            
            
            return Time;
        }

        public static float MetersToFeet(double meters)
        {
            return ((float)(meters * FeetPerMeter));
        }

        public static float FeetToMeters(double feet)
        {
            return ((float)(feet / FeetPerMeter));
        }

        public static float KnotsToMPH(double knots)
        {
            return ((float)(knots * MPHPerKnot));
        }

        public static double DegreesToRadians(double degrees)
        {
            return degrees * Math.PI / 180.0;
        }
        private static double RadiansToDegrees(double radians)
        {
            return radians * (180.0 / Math.PI);
        }

        public static string[] NMEAWords(string sentence)
        {
            string[] words = sentence.Split(',');
            int last = words.Length - 1;
            if (words[last].Contains("*"))
                words[last] = words[last].Substring(0, words[last].IndexOf("*"));
            return words;
        }
        
    }
}
